import { defineGlobalProperty, isRoomInterval } from '@/ayaka'
import StructureCache, { RegisterStructure } from '@/modules/structureCache'
import HarvestTaskManager from '@/room/task/base/harvest'
import TransportTaskManager from '@/room/task/base/transport'
import UpgradeTaskManager from '@/room/task/base/upgrade'
import { StorageResourceStandard } from '@/setting'

/**
 * link 控制器
 */
export default class LinkController {
    /**
     * 中央 link 转移能量任务名字
     */
    public static CENTER_LINK_TRANSFER_TASK_NAME = '中央link转移能量'

    /**
     * 中央 link 收集能量任务名字
     */
    public static CENTER_LINK_COLLECT_TASK_NAME = '中央link收集能量'

    /**
     * 运行
     */
    public static run(room: MyRoom) {
        LinkController.centerLinkWork(room)
    }

    /**
     * link 注册函数列表
     */
    protected static registerFns: RegisterStructure<STRUCTURE_LINK>[] = [
        LinkController.registerCenterLink,
        HarvestTaskManager.registerLink,
        UpgradeTaskManager.registerLink,
    ]

    /**
     * 注册 link
     */
    public static registerLink(room: MyRoom, links: StructureLink[]) {
        LinkController.registerFns.forEach((fn) => (links = fn(room, links)))
    }

    /**
     * 挂载
     */
    public static mount() {
        StructureCache.onNewStruct((room, newStructMap) => {
            const links = newStructMap[STRUCTURE_LINK]
            if (links) LinkController.registerLink(room, links)
        })
    }

    /**
     * 注册中央 link
     */
    public static registerCenterLink(room: MyRoom, links: StructureLink[]) {
        delete room.memory.centerLinkId
        const centerPos = new RoomPosition(room.memory.center[0], room.memory.center[1], room.name)
        const centerLink = links.find((link) => link.pos.inRangeTo(centerPos, 1))
        if (centerLink) {
            room.memory.centerLinkId = centerLink.id
        }
        return links.filter((link) => link !== centerLink)
    }

    /**
     * 中央 link 工作
     */
    public static centerLinkWork(room: MyRoom) {
        if (!room.memory.centerLinkId || !isRoomInterval(room, 5)) return

        const centerLink = Game.getObjectById(room.memory.centerLinkId)
        if (!centerLink) {
            delete room.memory.centerLinkId
            return
        }

        if (centerLink.store['energy'] > 0) {
            // 如果 upgradeLink 有空位就转移能量
            if (room.memory.upgrade.linkId) {
                const upgradeLink = Game.getObjectById(room.memory.upgrade.linkId)
                if (!upgradeLink) {
                    delete room.memory.upgrade.linkId
                    return
                }
                if (upgradeLink.store['energy'] === 0) {
                    if (!centerLink.cooldown) {
                        centerLink.transferEnergy(upgradeLink)
                    }
                    return
                }
            }

            if (
                TransportTaskManager.searchTransportTaskByName(room, LinkController.CENTER_LINK_COLLECT_TASK_NAME)
                    .length
            ) {
                return
            }

            let target: StructureStorage | StructureTerminal | StructureFactory | null = null
            const storage = room.storage
            const terminal = room.terminal
            if (terminal && terminal.store['energy'] < 20000 && terminal.store.getFreeCapacity() > 10000) {
                target = terminal
            } else if (
                storage &&
                storage.store['energy'] < StorageResourceStandard.energy[1] &&
                storage.store.getFreeCapacity() > 10000
            ) {
                target = storage
            } else if (terminal && terminal.store.getFreeCapacity() > 5000) {
                target = terminal
            } else if (storage && storage.store.getFreeCapacity() > 30000) {
                target = storage
            } else if (room.controller.level >= 7 && room.factory && room.factory.store.getFreeCapacity() >= 10000) {
                target = room.factory
            }
            if (target) {
                TransportTaskManager.addOneToOneTransportTask(
                    room,
                    LinkController.CENTER_LINK_COLLECT_TASK_NAME,
                    {
                        sourceId: centerLink.id,
                        targetId: target.id,
                        resInfo: {
                            energy: {
                                require: centerLink.store['energy'],
                                has: 0,
                            },
                        },
                    },
                    4,
                )
            }
        } else if (room.storage && room.storage.store['energy'] > 30000) {
            if (room.memory.upgrade.linkId) {
                const upgradeLink = Game.getObjectById(room.memory.upgrade.linkId)
                if (!upgradeLink || upgradeLink.store['energy'] > 0) {
                    return
                }

                // 添加
                if (
                    !TransportTaskManager.searchTransportTaskByName(room, LinkController.CENTER_LINK_TRANSFER_TASK_NAME)
                        .length
                ) {
                    TransportTaskManager.addOneToOneTransportTask(
                        room,
                        LinkController.CENTER_LINK_TRANSFER_TASK_NAME,
                        {
                            sourceId: room.storage.id,
                            targetId: centerLink.id,
                            resInfo: {
                                energy: {
                                    require: LINK_CAPACITY,
                                    has: 0,
                                },
                            },
                        },
                        4,
                    )
                }
            }
        }
    }
}

defineGlobalProperty('Link', {
    value: LinkController,
})
